
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include <unistd.h>
#include <fcntl.h>
#include <sys/syscall.h>
#include <linux/aio_abi.h>

 int io_setup(unsigned nr, aio_context_t *ctxp) {
	return syscall(__NR_io_setup, nr, ctxp);
}

 int io_destroy(aio_context_t ctx) {
	return syscall(__NR_io_destroy, ctx);
}

 int io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp) {
	return syscall(__NR_io_submit, ctx, nr, iocbpp);
}

 int io_getevents(aio_context_t ctx, long min_nr, long max_nr,
		struct io_event *events, struct timespec *timeout) {
	return syscall(__NR_io_getevents, ctx, min_nr, max_nr, events, timeout);
}


#define MAX_IO_NUM (10)
int main(const int argc, char *argv[])
{
    if (argc < 3)
    {
        printf("param less 3\r\n");
        exit(1);
    }

    char *data = argv[1];
    char *file_name = argv[2];


    printf("get data %s file_name %s\r\n", data, file_name);

    int fd;
    aio_context_t ctx;
    struct iocb io;
    struct iocb *pio[1] = {&io};
    struct io_event e[1];
    struct timespec timeout;

    memset(&ctx, 0, sizeof(ctx));
    if (io_setup(MAX_IO_NUM, &ctx))
    {
        printf("io setup error\r\n");
        exit(1);
    }

    fd = open(file_name, O_CREAT|O_RDWR);
    if (fd < 0)
    {
        perror("open error");
        io_destroy(ctx);
        exit(1);
    }

    memset(&io, 0, sizeof(io));
	io.aio_fildes = fd;
	io.aio_lio_opcode = IOCB_CMD_PWRITE;

//	io.aio_reqprio = 0;
	io.aio_buf = (uint64_t)data;
	io.aio_nbytes = strlen(data);
	io.aio_offset = 0;

   // io.aio_data = data;
    if (io_submit(ctx, 1, pio) != 1)
    {
        close(fd);
        io_destroy(ctx);
        perror("io submit error");
        exit(1);
    }

    timeout.tv_sec = 1;
    int count = 1;
    while (1)
    {
        printf("start get events %d times\r\n", count++);
        if (io_getevents(ctx, 1, 1, e, &timeout) == 1)
        {
            close(fd);
            printf("get it\r\n");
            break;
        }

    }

    io_destroy(ctx);

    return 0;
}